package org.kgduyjj.toolbox;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.log4j.Logger;

/**
 * 通用日期工具类
 * <p>
 * 你可以用一些日期代码使用它。</br>
 * 例如时间格式、计算时间、访问时间字符串、日期比较等
 * </p>
 * 
 * @author Kgduyjj
 * @since 2020-07-26
 * @version Alpha-1.42
 */
public final class DateUtil {

	/** 日志工具 */
	private static Logger logger = Logger.getLogger(DateUtil.class);

	/** 格式化 【标准日期时间】 */
	protected static final String DATE_STANDARD = "yyyy-MM-dd HH:mm:ss";
	/** 格式化 【标准日期】 */
	protected static final String DATE_DAY = "yyyy-MM-dd";
	/** 格式化 【无符号日期时间】 */
	protected static final String DATE_NONE = "yyyyMMddHHmmss";
	/** 格式化字符串 空值 */
	private static final String EMPTY = "";
	/** 一天的毫秒数 */
	public static final long ONE_DAY_MS = 86400000;
	/** 闰年二月份的天数 */
	private static final int FEBRUARY_OF_LEAP_YEAR_DAYS = 29;

	/**
	 * 私有化构造器
	 */
	private DateUtil() {
	}

	/**
	 * 校验日期格式化 Pattern 字符串是否为空
	 * 
	 * @param pattern
	 * @return
	 */
	private static boolean _isPatternEmpty(String pattern) {
		return (pattern == null || pattern.length() == 0);
	}

	/**
	 * 获取Calendar单例对象
	 * 
	 * @return instance of {@link Calendar}
	 */
	private static Calendar _getCalendar() {
		return Calendar.getInstance();
	}

	/**
	 * 获取日期指定位置的序号
	 * 
	 * @param date
	 * @param field
	 * @return
	 */
	private static int _getDateField(Date date, int field) {
		Calendar calendar = _getCalendar();
		calendar.setTime(date);
		return calendar.get(field);
	}

	/**
	 * 获取当前日期
	 * 
	 * @return
	 */
	public static Date now() {
		return new Date();
	}

	/**
	 * 将{@link java.util.Date} 转换为格式化日期字符串
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String format(Date date, String pattern) {
		if (date == null)
			return EMPTY;
		try {
			if (_isPatternEmpty(pattern)) {
				throw new IllegalArgumentException("Pattern不存在");
			}
			return new SimpleDateFormat(pattern).format(date);
		} catch (Exception e) {
			logger.error("Date Format Error", e);
			return EMPTY;
		}
	}

	/**
	 * 将{@link java.util.Date} 转换为格式化日期字符串
	 * 
	 * <pre>
	 * eg		2000-01-02 13:05:06 
	 * pattern	yyyy-MM-dd HH:mm:ss {@link DateUtil#DATE_STANDARD}
	 * </pre>
	 * 
	 * @param date
	 * @return
	 */
	public static String format(Date date) {
		return format(date, DATE_STANDARD);
	}

	/**
	 * 将格式化日期字符串转换为 {@link java.util.Date}
	 * 
	 * @param dateStr
	 * @param pattern
	 * @return
	 */
	public static Date parse(String dateStr, String pattern) {
		if (dateStr == null || EMPTY.equals(dateStr))
			return null;
		try {
			if (_isPatternEmpty(pattern)) {
				throw new IllegalArgumentException("Pattern不存在");
			}
			return new SimpleDateFormat(pattern).parse(dateStr);
		} catch (Exception e) {
			logger.error("Date Parse Error", e);
			return null;
		}
	}

	/**
	 * 将格式化日期字符串转换为 {@link java.util.Date}
	 * 
	 * <pre>
	 *  pattern	yyyy-MM-dd HH:mm:ss
	 * </pre>
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date parse(String dateStr) {
		return parse(dateStr, DATE_STANDARD);
	}

	/**
	 * 获得当前日期时间的字符串
	 * 
	 * <pre>
	 * eg		2000-01-02 13:05:06 
	 * pattern	yyyy-MM-dd HH:mm:ss
	 * </pre>
	 * 
	 * @return The current date string.
	 * @see {@link DateUtil#format}
	 */
	public static String currentDate() {
		return format(now(), DATE_STANDARD);
	}

	/**
	 * 获取传入日期时间为一年的第X个小时
	 * 
	 * @param date
	 * @return
	 */
	public static int getHourOfDay(Date date) {
		return _getDateField(date, Calendar.HOUR_OF_DAY);
	}

	/**
	 * 获取传入日期时间为本周的第X天
	 * 
	 * @param date
	 * @return
	 */
	public static int getDayOfWeek(Date date) {
		return _getDateField(date, Calendar.DAY_OF_WEEK);
	}

	/**
	 * 获取传入日期时间为当前的第X天
	 * 
	 * @param date
	 * @return
	 */
	public static int getDayOfMonth(Date date) {
		return _getDateField(date, Calendar.DAY_OF_MONTH);
	}

	/**
	 * 获取传入日期时间为一年的第X天
	 * 
	 * @param date
	 * @return
	 */
	public static int getDayOfYear(Date date) {
		return _getDateField(date, Calendar.DAY_OF_YEAR);
	}

	/**
	 * 获取传入日期时间为当月的第X周
	 * 
	 * @param date
	 * @return
	 */
	public static int getWeekOfMonth(Date date) {
		return _getDateField(date, Calendar.WEEK_OF_MONTH);
	}

	/**
	 * 获取传入日期时间为当年的第X周
	 * 
	 * @param date
	 * @return
	 */
	public static int getWeekOfYear(Date date) {
		return _getDateField(date, Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 获取传入日期时间为当年的第X月
	 * 
	 * @param date
	 * @return
	 */
	public static int getMonthOfYear(Date date) {
		return (_getDateField(date, Calendar.MONTH) + 1);
	}

	/**
	 * 获取传入日期为公元元年以后第X年
	 * 
	 * @param date
	 * @return
	 */
	public static int getYear(Date date) {
		return _getDateField(date, Calendar.YEAR);
	}

	/**
	 * 获取传入 {@link java.util.Date} 的凌晨0点0分0秒
	 * 
	 * <pre>
	 * eg.	2001-01-01 00:00:00
	 * </pre>
	 * 
	 * @param date
	 * @return
	 */
	public static Date toStartTimeOfDay(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = _getCalendar();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获取传入 {@link java.util.Date} 的凌晨23点59分59秒
	 * 
	 * <pre>
	 * eg.	2001-01-01 23:59:59
	 * </pre>
	 * 
	 * @param date
	 * @return
	 */
	public static Date toEndTimeOfDay(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = _getCalendar();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		return calendar.getTime();
	}

	/**
	 * 获取传入 {@link java.util.Date} 当月第一天的开始日期时间
	 * 
	 * <pre>
	 * eg.
	 * parameter :	2001-01-23 13:22:38
	 * return :	2001-01-01 00:00:00
	 * </pre>
	 * 
	 * @param date
	 * @return
	 */
	public static Date toStartDayOfMonth(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = _getCalendar();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		return toStartTimeOfDay(calendar.getTime());
	}

	/**
	 * 获取传入 {@link java.util.Date} 当月最后一天的结束日期时间
	 * 
	 * <pre>
	 * eg.
	 * parameter :	2001-01-23 13:22:38
	 * return :	2001-01-31 23:59:59
	 * </pre>
	 * 
	 * @param date
	 * @return
	 */
	public static Date toEndDayOfMonth(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = _getCalendar();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		return toEndTimeOfDay(calendar.getTime());
	}

	/**
	 * 获取传入 {@link java.util.Date} 当年第一天的开始日期时间
	 * 
	 * <pre>
	 * eg.
	 * parameter :	2001-07-23 13:22:38
	 * return :	2001-01-01 00:00:00
	 * </pre>
	 * 
	 * @param date
	 * @return
	 */
	public static Date toStartDayOfYear(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = _getCalendar();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_YEAR, 1);
		return toStartTimeOfDay(calendar.getTime());
	}

	/**
	 * 获取传入 {@link java.util.Date} 当年最后一天的结束日期时间
	 * 
	 * <pre>
	 * eg.
	 * parameter :	2001-07-23 13:22:38
	 * return :	2001-12-31 23:59:59
	 * </pre>
	 * 
	 * @param date
	 * @return
	 * 
	 */
	public static Date toEndDayOfYear(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = _getCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_YEAR, calendar.getActualMaximum(Calendar.DAY_OF_YEAR));
		return toEndTimeOfDay(calendar.getTime());
	}

	/**
	 * 获取传入 {@link java.util.Date} 上个月的同一时间，若传入日期时间的当月天数排序大于上月的最大天数，则默认的修改为上月最后一天
	 * 
	 * <pre>
	 * eg1.
	 * parameter:	2001-07-23 14:13:21
	 * return:	2001-06-23 14:13:21
	 * 
	 * eg2.
	 * parameter :	2001-03-30 13:22:38
	 * return :	2001-02-28 13:22:38
	 * </pre>
	 * 
	 * @param date
	 * @return
	 * 
	 * @see {@link DateUtil#getDayOfMonth(Date)}
	 */
	public static Date toPreviousMonth(Date date) {
		if (date == null)
			return null;
		Calendar calendar = _getCalendar();// 日历对象
		calendar.setTime(date);// 设置当前日期
		calendar.add(Calendar.MONTH, -1);// 月份减一
		int dayOfMonth = getDayOfMonth(calendar.getTime());
		// 若传入日期时间的当月天数排序大于上月的最大天数，则默认的修改为上月最后一天
		if (dayOfMonth > calendar.getActualMaximum(Calendar.DAY_OF_MONTH))
			calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		return calendar.getTime();
	}

	/**
	 * 获取传入 {@link java.util.Date} 前一天同一时间
	 * 
	 * <pre>
	 * eg.
	 * parameter:	2001-07-23 14:13:21
	 * return:	2001-07-22 14:13:21
	 * </pre>
	 * 
	 * @param date
	 * @return
	 */
	public static Date toYesterday(Date date) {
		if (date == null)
			return null;
		Calendar calendar = _getCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, -1);
		return calendar.getTime();
	}

	/**
	 * 通过字段获取日期比较差异。
	 * <p>
	 * 两个日期之间的计算差异必须在相同的自然年。
	 * </p>
	 * 
	 * @param beginDate
	 * @param endDate
	 * @param field
	 * @return
	 * 
	 * @see {@link DateUtil#_getDateField(Date, int)}
	 */
	private static int _getDifferenceValue(Date begin, Date end, int field) {
		if (begin == null && end == null) {
			throw new IllegalArgumentException("Two dates cannot be null");
		}
		if ((getYear(begin) == getYear(end))) {
			int bField = 0;
			int eField = 0;
			switch (field) {
			case Calendar.MONTH:
				bField = _getDateField(begin, field) + 1;
				eField = _getDateField(end, field) + 1;
				break;
			case Calendar.DAY_OF_WEEK:
			case Calendar.DAY_OF_MONTH:
			case Calendar.DAY_OF_YEAR:
			case Calendar.WEEK_OF_MONTH:
			case Calendar.WEEK_OF_YEAR:
			case Calendar.YEAR:
				bField = _getDateField(begin, field);
				eField = _getDateField(end, field);
				break;
			default:
				throw new IllegalArgumentException(String.format("It's unchecked field : $d", field));
			}
			return (eField - bField);
		} else if (field == Calendar.YEAR) {
			return (_getDateField(end, field) - _getDateField(begin, field));
		} else {
			throw new IllegalArgumentException("Two dates are not in the same natural year.");
		}
	}

	/**
	 * 获取两个日期的天数差值，以毫秒数计算
	 * 
	 * @param begin
	 * @param end
	 * @return
	 * 
	 * @see {@link DateUtil#_getDifferenceValue(Date, Date, int)}
	 */
	public static int getDifferenceDaysCount(Date begin, Date end) {
		if (begin == null || end == null) {
			throw new IllegalArgumentException(
					String.format("The dates([begin:%s] [end : %s]) cannot be null.", begin, end));
		}
		return BigInteger.valueOf(((end.getTime() - begin.getTime()) / ONE_DAY_MS)).intValue();
	}

	/**
	 * 获取两个日期在同周里的日差值
	 * 
	 * @param begin
	 * @param end
	 * @return
	 * 
	 * @see {@link DateUtil#_getDifferenceValue(Date, Date, int)}
	 */
	public static int periodDaysOfWeek(Date begin, Date end) {
		return _getDifferenceValue(begin, end, Calendar.DAY_OF_WEEK);
	}

	/**
	 * 获取两个日期在同月里的日差值
	 * 
	 * @param begin
	 * @param end
	 * @return
	 * 
	 * @see {@link DateUtil#_getDifferenceValue(Date, Date, int)}
	 */
	public static int periodDaysOfMonth(Date begin, Date end) {
		return _getDifferenceValue(begin, end, Calendar.DAY_OF_MONTH);
	}

	/**
	 * 获取取两个日期在同年的日差值
	 * 
	 * @param begin
	 * @param end
	 * @return
	 * 
	 * @see {@link DateUtil#_getDifferenceValue(Date, Date, int)}
	 */
	public static int periodDaysOfYear(Date begin, Date end) {
		return _getDifferenceValue(begin, end, Calendar.DAY_OF_YEAR);
	}

	/**
	 * 获取两个日期在同月的周差值
	 * 
	 * @param begin
	 * @param end
	 * @return
	 * 
	 * @see {@link DateUtil#_getDifferenceValue(Date, Date, int)}
	 */
	public static int periodWeeksOfMonth(Date begin, Date end) {
		return _getDifferenceValue(begin, end, Calendar.WEEK_OF_MONTH);
	}

	/**
	 * 获取两个日期在同年的周差值
	 * 
	 * @param begin
	 * @param end
	 * @return
	 * 
	 * @see {@link DateUtil#_getDifferenceValue(Date, Date, int)}
	 */
	public static int periodWeeksOfYear(Date begin, Date end) {
		return _getDifferenceValue(begin, end, Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 获取两个日期的月差值
	 * 
	 * @param begin
	 * @param end
	 * @return
	 * 
	 * @see {@link DateUtil#_getDifferenceValue(Date, Date, int)}
	 */
	public static int periodMonthOfYear(Date begin, Date end) {
		return _getDifferenceValue(begin, end, Calendar.MONTH);
	}

	/**
	 * 获取两个日期的年差值
	 * 
	 * @param begin
	 * @param end
	 * @return
	 * 
	 * @see {@link DateUtil#_getDifferenceValue(Date, Date, int)}
	 */
	public static int periodYears(Date begin, Date end) {
		return _getDifferenceValue(begin, end, Calendar.YEAR);
	}

	/**
	 * 获取前一天日期
	 * 
	 * @param date
	 * @return
	 */
	public static Date addDays(Date date, Integer days) {
		if (date == null) {
			return null;
		}
		Calendar calendar = _getCalendar();// 日历对象
		calendar.setTime(date);// 设置当前日期
		calendar.add(Calendar.DATE, days);
		return calendar.getTime();
	}

	/**
	 * 判断日期格式Pattern是否合法
	 * 
	 * <pre>
	 * DateUtil.isMatchingPattern("yyyy-MM-zx HH:mm:ss")	= false
	 * DateUtil.isMatchingPattern(null)			= false
	 * DateUtil.isMatchingPattern("")				= false
	 * DateUtil.isMatchingPattern("yyyy-MM-dd HH:mm:ss")	= true
	 * </pre>
	 * 
	 * @param pattern
	 * @return
	 * 
	 * @see {@link DateUtil#_isPatternEmpty(String)}
	 */
	public static boolean isMatchingPattern(String pattern) {
		if (_isPatternEmpty(pattern)) {
			return false;
		}
		try {
			SimpleDateFormat sdformat = new SimpleDateFormat(pattern);
			sdformat.setLenient(false);
			String dstring = sdformat.format(new Date());
			sdformat.parse(dstring);
		} catch (Exception e) {
			return false;
		}
		return true;
	}

	/**
	 * 判断传入的日期时间[time]是否是日期[day]一天内的时间
	 * 
	 * <pre>
	 * DateUtil.isTimeInDay(null, null)					= false 
	 * DateUtil.isTimeInDay(null, D(2001-02-01 00:00:00))			= false 
	 * DateUtil.isTimeInDay(D(2001-02-01 13:21:33), null)			= false 
	 * DateUtil.isTimeInDay(D(2001-02-02 13:21:33), D(2001-02-01 00:00:00))	= false 
	 * DateUtil.isTimeInDay(D(2001-02-01 13:21:33), D(2001-02-01 00:00:00))	= true
	 * </pre>
	 * 
	 * @param time
	 * @param day
	 * @return
	 * 
	 * @see {@link DateUtil#toStartTimeOfDay(Date)}
	 * @see {@link DateUtil#toEndTimeOfDay(Date)}
	 */
	public static boolean isTimeInDay(Date time, Date day) {
		if (time == null || day == null) {
			return false;
		}
		return (time.after(toStartTimeOfDay(day)) && time.before(toEndTimeOfDay(day)));
	}

	/**
	 * 判断传入的日期[day]是否是月份[month]一天内的时间
	 * 
	 * <pre>
	 * DateUtil.isDayInMonth(null, null)			= false 
	 * DateUtil.isDayInMonth(null, D(2001-02-01))		= false 
	 * DateUtil.isDayInMonth(D(2001-02-21), null)		= false 
	 * DateUtil.isDayInMonth(D(2001-02-21), D(2001-03-01))	= false 
	 * DateUtil.isDayInMonth(D(2001-02-21), D(2001-02-01))	= true
	 * </pre>
	 * 
	 * @param day
	 * @param month
	 * @return
	 * 
	 * @see {@link DateUtil#toStartDayOfMonth(Date)}
	 * @see {@link DateUtil#toEndDayOfMonth(Date)}
	 */
	public static boolean isDayInMonth(Date day, Date month) {
		if (day == null || day == month) {
			return false;
		}
		return (day.after(toStartDayOfMonth(month)) && day.before(toEndDayOfMonth(month)));
	}

	/**
	 * 判断传入日期是否为闰年
	 * 
	 * <pre>
	 * DateUtil.isLeapYear(null)	= false
	 * DateUtil.isLeapYear(D(2001))	= false
	 * DateUtil.isLeapYear(D(2000))	= true
	 * </pre>
	 * 
	 * @param pattern
	 * @return
	 * 
	 * @see {@link DateUtil#getDayOfMonth(Date)}
	 * @see {@link DateUtil#toEndDayOfMonth(Date)}
	 * @see {@link DateUtil#FEBRUARY_OF_LEAP_YEAR_DAYS}
	 */
	public static boolean isLeapYear(Date date) {
		if (date == null) {
			return false;
		}
		Calendar calendar = _getCalendar();
		calendar.setTime(date);
		calendar.set(Calendar.MONTH, Calendar.FEBRUARY);
		return (getDayOfMonth(toEndDayOfMonth(calendar.getTime())) == FEBRUARY_OF_LEAP_YEAR_DAYS);
	}

	/**
	 * 判断传入日期是否为当月最后一天
	 * 
	 * <pre>
	 * DateUtil.isEndOfMonth(null)		= false
	 * DateUtil.isEndOfMonth(D(2001-01-21))	= false
	 * DateUtil.isEndOfMonth(D(2001-01-31))	= true
	 * </pre>
	 * 
	 * @param date
	 * @return
	 */
	public static boolean isEndOfMonth(Date date) {
		Calendar calendar = _getCalendar();
		if (date == null) {
			return false;
		}
		calendar.setTime(date);
		int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
		if (dayOfMonth == calendar.getActualMaximum(Calendar.DAY_OF_MONTH)) {
			return true;
		}
		return false;
	}

	/**
	 * 判断传入日期是否为当月最后一天
	 * 
	 * <pre>
	 * DateUtil.isEndOfYear(D(2001-12-31))	= true
	 * DateUtil.isEndOfYear(D(2001-12-21))	= false
	 * DateUtil.isEndOfYear(D(2001-01-31))	= false
	 * </pre>
	 * 
	 * @param date
	 * @return
	 */
	public static boolean isEndOfYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		if (date != null) {
			calendar.setTime(date);
		}
		int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
		if (dayOfYear == calendar.getActualMaximum(Calendar.DAY_OF_YEAR)) {
			return true;
		}
		return false;
	}

	/**
	 * 判定传入日期是否为当前日期的前一天
	 * 
	 * <pre>
	 * #if Today is D(2001-02-10) :
	 * DateUtil.isYesterday(D(2001-02-11))	= false
	 * DateUtil.isYesterday(D(2001-02-09))	= true
	 * 
	 * #if Today is D(2001-01-01) :
	 * DateUtil.isYesterday(D(2001-01-01))	= false
	 * DateUtil.isYesterday(D(2000-12-31))	= true
	 * </pre>
	 * 
	 * @param date
	 * @return
	 * 
	 * @see {@link DateUtil#toYesterday(Date)}
	 * @see {@link DateUtil#isTimeInDay(Date, Date)}
	 */
	public static boolean isYesterday(Date date) {
		if (date == null) {
			return false;
		}
		Date yesterday = toYesterday(now());
		return isTimeInDay(date, yesterday);
	}

	/**
	 * 判断两个日期是否为同月
	 * 
	 * <pre>
	 * DateUtil.isSameMonth(null, null)		= false
	 * DateUtil.isSameMonth(D(2000-03),null)		= false
	 * DateUtil.isSameMonth(null,D(2000-03))		= false
	 * DateUtil.isSameMonth(D(2001-03),D(2000-04))	= false
	 * DateUtil.isSameMonth(D(2001-03),D(2000-03))	= true
	 * </pre>
	 * 
	 * @param subject
	 * @param other
	 * @return
	 * 
	 * @see {@link DateUtil#getMonthOfYear(Date)}
	 */
	public static boolean isSameMonth(Date subject, Date other) {
		if (subject == null || other == null) {
			return false;
		}
		return (getMonthOfYear(subject) == getMonthOfYear(other));
	}

	/**
	 * 判断两个日期是否为同日
	 * 
	 * 
	 * <pre>
	 * DateUtil.isSameDay(null, null)				= false
	 * DateUtil.isSameDay(D(2001-03-03),null)			= false
	 * DateUtil.isSameDay(null,D(2000-03-01))			= false
	 * DateUtil.isSameDay(D(2001-03-03),D(2000-03-01))	= false
	 * DateUtil.isSameDay(D(2001-04-03),D(2000-03-03))	= true
	 * DateUtil.isSameDay(D(2001-03-03),D(2000-03-03))	= true
	 * </pre>
	 * 
	 * @param subject
	 * @param other
	 * @return
	 * 
	 * @see {@link DateUtil#getDayOfMonth(Date)}
	 */
	public static boolean isSameDay(Date subject, Date other) {
		if (subject == null || other == null) {
			return false;
		}
		return (getDayOfMonth(subject) == getDayOfMonth(other));
	}

	/**
	 * 判断两个日期是否为同月同日
	 * 
	 * <pre>
	 * DateUtil.isSameDay(null, null)				= false
	 * DateUtil.isSameDay(D(2001-03-03),null)			= false
	 * DateUtil.isSameDay(null,D(2000-03-01))			= false
	 * DateUtil.isSameDay(D(2001-03-03),D(2000-03-01))	= false
	 * DateUtil.isSameDay(D(2001-04-03),D(2000-03-03))	= false
	 * DateUtil.isSameDay(D(2001-03-03),D(2000-03-03))	= true
	 * </pre>
	 * 
	 * @param subject
	 * @param other
	 * @return
	 * 
	 * @see {@link DateUtil#isSameMonth(Date, Date)}
	 * @see {@link DateUtil#isSameDay(Date, Date)}
	 */
	public static boolean isSameMonthAndDay(Date subject, Date other) {
		if (subject == null || other == null) {
			return false;
		}
		return (isSameMonth(subject, other) && isSameDay(subject, other));
	}

	/**
	 * 判断日期大小，参数顺序为[first,second]
	 * 
	 * <pre>
	* DateUtil.isFirstEarlier(null, null)					= false
	* DateUtil.isFirstEarlier(D(2001-03-03 13:15:25),null)			= false
	* DateUtil.isFirstEarlier(null,D(2001-03-03 13:15:25))			= false
	* DateUtil.isFirstEarlier(D(2001-03-03 13:15:26),D(2001-03-03 13:15:25))	= false
	* DateUtil.isFirstEarlier(D(2001-03-04 13:15:25),D(2001-03-03 13:15:25))	= false
	* DateUtil.isFirstEarlier(D(2001-03-03 13:15:24),D(2001-03-03 13:15:25))	= true
	* DateUtil.isFirstEarlier(D(2001-03-02 13:15:24),D(2001-03-03 13:15:25))	= true
	 * </pre>
	 * 
	 * @param first
	 * @param second
	 * @return
	 */
	public static boolean isFirstEarlier(Date first, Date second) {
		if (first == null || second == null) {
			return false;
		}
		return (second.getTime() > first.getTime());
	}

}
